package system.security;

import framework.client.WebUserAgent;
import framework.defined.SystemDefined;
import framework.security.Account;
import framework.security.AccountLoader;
import framework.security.FunctionPermission;
import framework.utils.RequestUtil;
import framework.utils.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import system.entity.SysFunc;
import system.entity.SysLoginFailLimit;
import system.entity.SysPermission;
import system.entity.SysUser;
import system.service.sys.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 安全组件用户的默认加载器
 */
@Slf4j
@Component
public class AccountLoaderImpl implements AccountLoader {

    @Autowired
    private SysUserService userService;
    @Autowired
    private SysPermissionService permissionService;
    @Autowired
    private SysFuncService funcService;
    @Autowired
    private SysLoginFailLimitService loginFailLimitService;
    @Autowired
    private SysConfigService configService;

    @Override
    public Account loadUserByUsername(String username) {
        //用户加载
        SysUser user = this.userService.loadByUsername(username);
        if (user == null)
            return null;
        //返回用户对象
        return new UserAccount(user);
    }

    @Override
    public Account loadUserById(Long id) {
        SysUser user = this.userService.loadById(id);
        if (user == null)
            return null;
        //返回用户对象
        return new UserAccount(user);
    }

    /**
     * 加载用户的权限列表
     *
     * @param id
     * @return
     */
    @Override
    public List<String> loadPermissions(Long id) {
        List<String> permissions = this.userService.loadUserPermissions(id);
        return permissions;
    }

    /**
     * 加载功能权限表(即菜单)
     *
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public List<FunctionPermission> loadFunctionPermission() {
        String cacheKey = "security_loadFunctionPermission";
        List<FunctionPermission> f = new ArrayList<>();
        f = configService.getConfigOfVersion(cacheKey, f.getClass());
        if (f != null) return new ArrayList<>(f);

        //请求全部功能清单
        List<SysFunc> list = this.funcService.load(new SysFunc());
        f = new ArrayList<>(list.size());
        for (SysFunc func : list) {
            f.add(new FunctionPermission(func.getFunPath(), func.getPermissionId(), func.getFunMethod()));
        }

        //添加到配置项
        configService.setConfigOfVersion(cacheKey, f);

        //
        return f;
    }

    /**
     * 加载所有的权限
     *
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public List<String> loadAllPermission() {
        String cacheKey = "security_loadAllPermission";
        List<String> f = new ArrayList<>();
        f = configService.getConfigOfVersion(cacheKey, f.getClass());
        if (f != null) return new ArrayList<>(f);

        //加载数据
        SysPermission query = new SysPermission();
        query.setIsDisabled(SystemDefined.NO_VALUE);
        List<SysPermission> list = this.permissionService.load(query);
        f = list.stream().map(p -> p.getId()).collect(Collectors.toList());

        //添加到配置项
        configService.setConfigOfVersion(cacheKey, f);

        //
        return f;
    }

    /**
     * 因登录失败次数超限已被限制登录的时间秒数
     *
     * @param username
     * @return
     */
    @Override
    public int loginFailLimit(String username) {
        SysLoginFailLimit limit = loginFailLimitService.loadById(username);
        if (limit == null)
            return 0;
        if (limit.getExpireTime() == null)
            return 0;

        Date now = new Date();
        int sec = (int) (limit.getExpireTime().getTime() - now.getTime()) / 1000;
        if (sec > 0) {
            //未到期，输出秒值
            return sec;
        }

        //删除已到期数据
        loginFailLimitService.deleteById(username);

        //
        return 0;
    }

    /**
     * 登录成功
     *
     * @param id
     * @param username
     */
    @Override
    public void loginSuccessful(String username, Long id) {
        HttpServletRequest request = ServletUtil.getRequest();
        //添加记数
        String clientIp = RequestUtil.getClientIp(request);
        WebUserAgent userAgent = new WebUserAgent(request);
        //添加登录日志
        userService.loginSuccessful(username
                , id
                , clientIp
                , userAgent.getOs()
                , userAgent.getBrowser());
    }

    @Override
    public void loginUnsuccessful(String username, String cause) {
        HttpServletRequest request = ServletUtil.getRequest();
        //添加记数
        String clientIp = RequestUtil.getClientIp(request);
        WebUserAgent userAgent = new WebUserAgent(request);
        //添加登录日志
        userService.loginUnsuccessful(username
                , clientIp
                , userAgent.getOs()
                , userAgent.getBrowser()
                , cause
        );
    }

    /**
     * 登出完成
     *
     * @param id
     */
    @Override
    public void logoutSuccessful(Long id) {
        userService.logoutSuccessful(id);
    }

}
